-
Notifications
You must be signed in to change notification settings - Fork 16
chore: Improve Logging #634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…w/appear in terminal for some reason.
| </root> | ||
|
|
||
| <!-- <logger name="org.apache.hc.client5.http.wire" level="DEBUG"/>--> | ||
| <!-- <logger name="org.apache.http.wire" level="DEBUG"/>--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wire logs on unit tests finally
| <root level="INFO"/> | ||
| <logger name="org.springframework.web" level="INFO"/> | ||
| <logger name="org.apache.hc.client5.http.wire" level="DEBUG"/> | ||
| <logger name="org.apache.http.wire" level="DEBUG"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logback.xml takes precedence
| } else { | ||
| log.info("LLM request success"); | ||
| } | ||
| log.debug("Response content:\n{}", content); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Major)
I believe this needs to be removed. There was request from Joule on the same and we intentionally removed all request and response content logging in the past.
- https://github.com/SAP/ai-sdk-java-backlog/issues/290
- fix: [Core] Remove any logging of response request body #504
If there are no objections, I will remove this before the PR is merged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreeing with @rpanackal
Also some side-rules:
- For highly repetitive messages and/or huge message footprints, use
traceinstead ofdebug. - Do not use new-lines
\nin log messages.
core/src/main/java/com/sap/ai/sdk/core/common/ClientResponseHandler.java
Outdated
Show resolved
Hide resolved
| final T value = objectMapper.readValue(content, successType); | ||
| val timeHeaders = response.getHeaders("x-upstream-service-time"); | ||
| if (timeHeaders.length > 0) { | ||
| log.info("LLM request success with duration:{}", timeHeaders[0].getValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Question/Minor)
-
Are all current and future messages to AI Core LLM requests? This is a generic/general response handling class 🤔
-
I wouldn't use "success", rather "completed". The user may have different understanding for "success".
-
Can we add HTTP response size to the message? e.g.
13KB
response.getEntity().getContentLength()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ClientResponseHandler is only invoked for openai and orchestration, and therefore "LLM requests" is not entirely wrong but ofc no guarantees for the future.
I have changed the request message to be more descriptive, including the response size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiClient.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/sap/ai/sdk/core/common/ClientResponseHandler.java
Outdated
Show resolved
Hide resolved
| throw new OrchestrationClientException( | ||
| "Request to Orchestration service failed for " + path, e); | ||
| } finally { | ||
| MDC.clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have 2 requests running simultaneously, could the shorter one clear the context of the longer one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MDC is thread local, so normally this shouldn't be a problem.
That said, we need to make sure that the MDC state is set and consumed per request level as the context is finally cleared after each request. A counter example would be setting the MDC in OrchestrationModuleConfig object and using it across multiple requests. Here the MDC context set in config creation is cleared on first request and cannot be expected to be available on subsequent requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to point out: If you are ever outside of the thread, you will lose the MDC parameters.
It's not obvious when/whether that happens. For example, if we ever decide to use Resilience (or any other form of TimeLimiter), then the approach will stop working I think.
core/src/main/java/com/sap/ai/sdk/core/common/ClientResponseHandler.java
Outdated
Show resolved
Hide resolved
foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiClient.java
Outdated
Show resolved
Hide resolved
| val sizeInfo = entityLength >= 0 ? String.format("%.1fKB", entityLength / 1024.0) : "unknown"; | ||
| log.debug( | ||
| "[reqId={}] {} request completed successfully with duration={}, size={}.", | ||
| MDC.get("reqId"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Major/Question)
Why do you put MDC information here? They should be part of the general log pattern.
Edit: Normally these diagnostic context values are part of log patterns, instead of log messages. But I don't have a strong opinion against that.
What made you choose this String format with [...] and foo=bar? Are there any best practices that suggest that technical format? Do you expect tools to consume / evaluate the message?
Edit: We may have to define a so-called Architecture Decision Record to write down our decision what kind of pattern / format we prefer for variable based values.
Also please improve code format, this looks bad.
Edit: Have you considered using re-usable String constants? This would also help understanding these are dedicated diagnostic variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the first two question
Edit: Normally these diagnostic context values are part of log patterns, instead of log messages.
My initial approach was applying the MDC on log patterns. But this lead to having awkward atifacts in all logs because there variable are not defined/expected to be available for them. Conditional patterns made the pattern itself unreadable and difficult to apply symbols to easily discern parts of the log.
What made you choose this String format with [...] and foo=bar? Are there any best practices that suggest that technical format? Do you expect tools to consume / evaluate the message?
I do not expect them to be machine readable. But purely thought of adopting a log format this is extendable incase we want to log additional information eg: "... status=OK". We choose purely descriptive messages instead. No strong opinion.
Have you considered using re-usable String constants? This would also help understanding these are dedicated diagnostic variables.
We can definitely add String constants.
...penai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiChatCompletionResponse.java
Outdated
Show resolved
Hide resolved
…onmodels/openai/OpenAiChatCompletionResponse.java
Context
AI/ai-sdk-java-backlog#295.
Printing useful Logs for AI SDK. The following example shows a tool execution:
Feature scope:
Credential type not found or not recognised in service binding.DotEnvinstance and reduce log messages #635Found a service key in environment variable AICORE_SERVICE_KEY.DotEnvinstance and reduce log messages #635Definition of Done
Tests cover the scope aboveError handling created / updated & covered by the tests aboveAligned changes with the JavaScript SDKDocumentation updatedRelease notes updated